package drill

import (
	"database/sql"
	"fmt"
	"sync"
	"time"

	_ "modernc.org/sqlite"
)

// DrillConfig 钻机配置结构体
type DrillConfig struct {
	D          float64 `json:"d"`           // 直径，单位：米
	Kn         float64 `json:"kn"`          // 螺杆转速系数，单位：rev/gal，取值范围：0.25-0.3
	Kt         float64 `json:"kt"`          // 螺杆扭矩系数，单位：ft-lb/psi，取值范围：9.5-9.9
	DeltaP     float64 `json:"delta_p"`     // 压力，单位：psi，取值：466或585
	CreateTime string  `json:"create_time"` // 写入时间，格式：yyyymmdd
	Status     int     `json:"status"`      // 可用状态，0代表不可用，1代表可用
}

// DrillConfigManager 配置管理器
type DrillConfigManager struct {
	db      *sql.DB
	dataDir string
	current *DrillConfig
}

var (
	instance *DrillConfigManager
	once     sync.Once
	lock     sync.Mutex
)

func Get() *DrillConfigManager {
	once.Do(func() {
		instance, _ = setup("db/drill_config.db")
		lateast, er := instance.GetLatestConfig()
		//默认值
		if er != nil || lateast == nil {
			fmt.Println("未找到配置文件，使用默认值")
			instance.current = &DrillConfig{
				D:      10.5,
				Kn:     0.28,
				Kt:     9.7,
				DeltaP: 585,
			}
		} else {
			instance.current = lateast
			fmt.Printf("已找到配置文件，使用配置文件值:%v", instance.current)
		}
	})
	return instance
}

// NewDrillConfigManager 创建新的配置管理器
func setup(dataSourceName string) (*DrillConfigManager, error) {
	db, err := sql.Open("sqlite", dataSourceName)
	if err != nil {
		return nil, fmt.Errorf("failed to open database: %v", err)
	}

	// Create table if not exists
	createTableSQL := `
    CREATE TABLE IF NOT EXISTS drill_configs (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        d REAL NOT NULL,
        kn REAL NOT NULL,
        kt REAL NOT NULL,
        delta_p REAL NOT NULL,
        create_time TEXT NOT NULL,
        status INTEGER NOT NULL
    );`

	_, err = db.Exec(createTableSQL)
	if err != nil {
		return nil, fmt.Errorf("failed to create table: %v", err)
	}
	return &DrillConfigManager{
		db:      db,
		dataDir: dataSourceName,
	}, nil
}

func (m *DrillConfigManager) GetCurrentConfig() *DrillConfig {
	lock.Lock()
	defer lock.Unlock()
	return m.current
}

// WriteConfig 写入新的配置
// 每次写入时，会将所有现有配置的状态更新为0，新配置的状态为1
func (m *DrillConfigManager) WriteConfig(config DrillConfig) error {
	lock.Lock()
	defer lock.Unlock()
	tx, err := m.db.Begin()
	if err != nil {
		return fmt.Errorf("failed to begin transaction: %v", err)
	}
	defer tx.Rollback()

	// Update all existing configs status to 0
	_, err = tx.Exec("UPDATE drill_configs SET status = 0 WHERE status = 1")
	if err != nil {
		return fmt.Errorf("failed to update existing configs: %v", err)
	}

	// Validate new config
	if err := m.validateConfig(config); err != nil {
		return fmt.Errorf("config validation failed: %v", err)
	}

	// Set new config status to 1
	config.Status = 1

	// Set create time if empty
	if config.CreateTime == "" {
		config.CreateTime = time.Now().Format("20060102150405")
	}

	// Insert new config
	insertSQL := `
    INSERT INTO drill_configs (d, kn, kt, delta_p, create_time, status)
    VALUES (?, ?, ?, ?, ?, ?)`
	_, err = tx.Exec(insertSQL, config.D, config.Kn, config.Kt, config.DeltaP, config.CreateTime, config.Status)
	if err != nil {
		return fmt.Errorf("failed to insert new config: %v", err)
	}

	// Commit transaction
	if err = tx.Commit(); err != nil {
		return fmt.Errorf("failed to commit transaction: %v", err)
	}
	m.current = &config
	fmt.Println("写入数据成功：", config.Kn, config.Kt, config.DeltaP)
	return nil
}

// GetLatestConfig 获取最新的可用配置（status=1）
func (m *DrillConfigManager) GetLatestConfig() (*DrillConfig, error) {
	query := `
    SELECT d, kn, kt, delta_p, create_time, status
    FROM drill_configs
    WHERE status = 1
    ORDER BY id DESC
    LIMIT 1`

	row := m.db.QueryRow(query)

	var config DrillConfig
	err := row.Scan(&config.D, &config.Kn, &config.Kt, &config.DeltaP, &config.CreateTime, &config.Status)
	if err != nil {
		if err == sql.ErrNoRows {
			return nil, fmt.Errorf("no available config found")
		}
		return nil, fmt.Errorf("failed to query config: %v", err)
	}

	return &config, nil
}

// validateConfig 验证配置数据
func (m *DrillConfigManager) validateConfig(config DrillConfig) error {
	// 验证Kn取值范围
	// if config.Kn < 0.25 || config.Kn > 0.3 {
	// 	return fmt.Errorf("螺杆转速系数Kn必须在0.25-0.3之间，当前值：%.2f", config.Kn)
	// }

	// // 验证Kt取值范围
	// if config.Kt < 9.5 || config.Kt > 9.9 {
	// 	return fmt.Errorf("螺杆扭矩系数Kt必须在9.5-9.9之间，当前值：%.2f", config.Kt)
	// }

	// // 验证DeltaP取值
	// if config.DeltaP != 466 && config.DeltaP != 585 {
	// 	return fmt.Errorf("压力DeltaP必须是466或585，当前值：%.0f", config.DeltaP)
	// }

	// 验证D必须为正数
	if config.D <= 0 {
		return fmt.Errorf("直径D必须为正数，当前值：%.2f", config.D)
	}

	return nil
}

// Close closes the database connection
func (m *DrillConfigManager) Close() error {
	return m.db.Close()
}
